#include"net/dns.hpp"
#include<arpa/inet.h>
#include<netdb.h>

#undef  xuser
#define xuser mixc::net_dns::inc
#include"algo/sort.hpp"

namespace mixc::net_dns::origin::dns{
    inc::array<ipv4> get_address_v4(inc::c08 const & hostname){
        using aip_t             = addrinfo *;
        auto    info            = aip_t{};
        auto    count           = uxx{};

        if (getaddrinfo(asciis(hostname), nullptr, nullptr, & info) == 0){
            for(auto node = info; node != nullptr; node = node->ai_next){
                if (node->ai_family == AF_INET){
                    count      += 1;
                }
            }

            if (count == 0){
                return {};
            }

            auto && temp        = inc::array<u32>{ length(count) };
            auto    ip          = ipv4{};
            auto    i           = uxx{};
            auto    j           = uxx{};

            for(auto node = info; node != nullptr; node = node->ai_next){
                if (node->ai_family == AF_INET){
                    ip.from_net(((sockaddr_in *)node->ai_addr)->sin_addr.s_addr);
                    temp[i++]   = ip->local_form;
                }
            }

            inc::sort::heap(temp);

            for(i = 1, count = 1; i < temp->length; i++){
                if (temp[i - 1] != temp[i]){
                    count      += 1;
                }
            }

            inc::array<ipv4> result{ length(count) };

            for(result[0].from_local(temp[0]), i = 1, j = 1; i < temp->length; i++){
                if (temp[i - 1] != temp[i]){
                    result[j++].from_local(temp[i]);
                }
            }

            freeaddrinfo(info);
            return result;
        }
        return {};
    }
}
